package com.my.service.impl;

import com.my.domain.dto.Column;
import com.my.domain.dto.Table;
import com.my.service.DbService;
import lombok.extern.log4j.Log4j;
import org.springframework.stereotype.Service;


import java.util.Map;

/**
 * Created by Administrator on 2017/6/12.
 */
@Log4j
@Service
public class DbServiceImpl implements DbService{
    //save compare result
    private static StringBuilder[] sb = {new StringBuilder(), new StringBuilder(), new StringBuilder(),
            new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder(), new StringBuilder()};

    @Override
    public StringBuilder[] compare(String firstDbName, String secondDbName, Map<String, Table> firstTableMap, Map<String, Table> secondTableMap) throws Exception{
        clear();
        //遍历A库Map
        for (Map.Entry <String, Table> entry : firstTableMap.entrySet()) {
            String tableName = entry.getKey();
            Table tableFirst = entry.getValue();//获得A中的表
            Table tableSecond = secondTableMap.get(tableName);//尝试从B中获得同名表
            if (tableSecond == null) { //如果获得表为空，说明A存在，B不存在
                append(firstDbName, secondDbName, tableFirst, null, null,1);
            } else { //表相同，判断字段、字段类型、字段长度
                for (Map.Entry <String, Column> columnEntry : entry.getValue().getColumnMap().entrySet()) {
                    String column = columnEntry.getKey();
                    Column columnFirst = entry.getValue().getColumnMap().get(column);//获得A中的列
                    Column columnSecond = secondTableMap.get(tableName).getColumnMap().get(column);//尝试从B中获得同名列
                    if (columnSecond == null) {//如果列名为空，说明A存在，B不存在
                        append(firstDbName, secondDbName, tableFirst,  columnFirst, null, 3);
                    } else {//说明两者都存在
                        if (!columnFirst.getColumnDataType().equals(columnSecond.getColumnDataType()))//字段类型不一致
                            append(firstDbName, secondDbName, tableFirst, columnSecond, columnFirst, 5);
                        else if (columnFirst.getColumnLength() != columnSecond.getColumnLength())//字段长度不一致
                            append(firstDbName, secondDbName, tableFirst, columnSecond, columnFirst, 6);
                        else if (columnFirst.getColumnIsPri() != columnSecond.getColumnIsPri())
                            append(firstDbName, secondDbName, tableFirst, columnFirst, null, 7);
                        else
                            append(firstDbName, secondDbName, tableFirst, columnFirst, null,8);
                    }
                }
            }
        }

        //遍历B库Map
        for (Map.Entry <String, Table> entry : secondTableMap.entrySet()) {
            String tableName = entry.getKey();
            Table tableSecond = entry.getValue();//尝试从B中获得同名表
            Table tableFirst = firstTableMap.get(tableName);//获得A中的表
            if (tableFirst == null) { //如果获得表为空，说明B存在，A不存在
                append(firstDbName, secondDbName, tableSecond,null, null,2);
            }else{ //表相同，判断字段、字段类型、字段长度
                for (Map.Entry <String, Column> columnEntry : entry.getValue().getColumnMap().entrySet()) {
                    String column = columnEntry.getKey();
                    Column columnSecond = entry.getValue().getColumnMap().get(column);//获得B库中的列
                    Column columnFirst = firstTableMap.get(tableName).getColumnMap().get(column);//尝试从A中获得同名列
                    if (columnFirst == null) {//如果列名为空，说明B存在，A不存在
                        append(firstDbName, secondDbName, tableSecond,  columnSecond, null, 4);
                    }
                }
            }
        }
        insert(firstDbName, secondDbName);
        return  sb;
    }


    public static void append(String firstDbName, String secondDbName, Table table,Column column, Column other, int flag) {
        switch (flag) {
            case 1:
                log.info("1、"+firstDbName+"存在，"+secondDbName+"不存在的表："+table.getTableName());
                sb[0].append(table.getTableName()).append("\n");
                break;
            case 2:
                log.info("2、"+firstDbName+"不存在，"+secondDbName+"存在的表："+table.getTableName());
                sb[1].append(table.getTableName()).append("\n");
                break;
            case 3:
                log.info("3、"+firstDbName+"存在，"+secondDbName+"不存在的字段："+table.getTableName()+" | "+column.getColumnName());
                sb[2].append(table.getTableName()).append(" | ").append(column.getColumnName()).append("\n");
                break;
            case 4:
                log.info("4、"+firstDbName+"不存在，"+secondDbName+"存在的字段："+table.getTableName()+" | "+column.getColumnName());
                sb[3].append(table.getTableName()).append(" | ").append(column.getColumnName()).append("\n");
                break;
            case 5:
                log.info("5、表和字段都相同，但字段类型不同的内容："+table.getTableName()+" | "+column.getColumnName()+" | "+column.getColumnDataType());
                sb[4].append(table.getTableName()).append(" | ").append(column.getColumnName()).append(" | (").append(column.getColumnDataType())
                        .append(",").append(other.getColumnDataType()).append(")\n");
                break;
            case 6:
                log.info("6、表和字段、字段类型都相同，但字段长度不同的内容："+table.getTableName()+" | "+column.getColumnName()+" | "+column.getColumnLength());
                sb[5].append(table.getTableName()).append(" | ").append(column.getColumnName()).append(" | ").append(column.getColumnDataType()).append(" | (").
                        append(column.getColumnLength()).append(",").append(other.getColumnLength()).append(")\n");
                break;
            case 7:
                log.info("7、表和字段、字段类型，字段长度都相同，但主键不同的内容："+table.getTableName()+" | "+column.getColumnName()+" | "+column.getColumnLength());
                sb[6].append(table.getTableName()).append(" | ").append(column.getColumnName()).append(" | ").append(column.getColumnDataType()).append(" | ").
                        append(column.getColumnLength()).append("|").append(column.getColumnIsPri()).append("\n");
                break;
            case 8:
                log.info("8、表和字段、字段类型，字段长度,主键都相同："+table.getTableName()+" | "+column.getColumnName()+" | "+column.getColumnLength() + " | "+ column.getColumnDataType());
                sb[7].append(table.getTableName()).append(" | ").append(column.getColumnName()).append(" | ").append(column.getColumnDataType()).append(" | ")
                        .append(column.getColumnLength()).append("|").append(column.getColumnIsPri() == 1 ? "Yes" : "No").append("\n");
                break;
            default:
                break;
        }
    }

    public static  void insert(String firstDbName, String secondDbName) {
        sb[0].insert(0, firstDbName+"存在，"+secondDbName+"不存在的表：\n");
        sb[1].insert(0, firstDbName+"不存在，"+secondDbName+"存在的表：\n");
        sb[2].insert(0, firstDbName+"存在，"+secondDbName+"不存在的字段：\n");
        sb[3].insert(0, firstDbName+"不存在，"+secondDbName+"存在的字段：\n");
        sb[4].insert(0, "表和字段都相同，但字段类型不同的内容("+firstDbName+","+secondDbName+")\n");
        sb[5].insert(0, "表和字段、字段类型都相同，但字段长度不同的内容("+firstDbName+","+secondDbName+")：\n");
        sb[6].insert(0, "表和字段、字段类型，字段长度都相同，但主键不同的内容：\n");
        sb[7].insert(0, "表和字段、字段类型，字段长度,是否主键都相同：\n");
    }

    public static void clear() {
        for (int i = 0; i < sb.length; i++) {
            sb[i].delete(0, sb[i].length());
        }
    }
}
